home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / XCMD libraries 960603 / xcmdStrings.cp < prev    next >
Text File  |  1996-05-29  |  9KB  |  407 lines

  1. #include <UException.h>
  2. //    © Paul B. Beeken, Work In Progress, 1994-5
  3. //    Knowledge Software Consulting.
  4. //
  5. //    These files are a mindlessly simple wrapper class for the
  6. //    basic XCMD operations.  Only one instance of the xcmdBase class is
  7. //    generated per XCMD call but there may be many instances of the XCMDString
  8. //    class.  I have used these classes to whip out XCMD/XFCNs within hours of
  9. //    receiving the specs.  They work great for me but I will always consider 
  10. //    suggestions.
  11. //
  12. //    Please, please, please, in the unlikely event you should use this stuff
  13. //    for some commercial application I would appreciate you contacting me.  If
  14. //    its for your own use, use away. Send email: knowsoft@ios.com
  15. //
  16. //    As always: this file is presented as is with no warrantees expressed or implied.
  17. //    Swim at your own risk, etc. etc.
  18. //
  19. //    A serious improvement over the previous version.
  20. //    11/11/95    because of some problems with stricter type checking under
  21. //               CW 7 I have changed the scheme for string storage.  I 
  22. //               allocate a single storage pointer which will hold the pascal 
  23. //               length byte and the null terminator.  If I need a c string I 
  24. //               simply pass a pointer to the beginning of the c like 
  25. //               portion.  A pascal string request gets a pointer to the very 
  26. //               beginning.  Designing this way required more attention to 
  27. //               details over the previous brain-dead method.
  28. //  05/28/96    CW9 made some changes to <HyperXCmd.h> I've incorporated those changes
  29. //                 here.
  30. //#include    <strings.h>
  31. #include    "xcmdStrings.h"
  32.  
  33. const    int MAX_PSIZE    = 255;
  34.  
  35. #define NoCLIB 1
  36.  
  37. #ifdef NoCLIB
  38. //    A local function to avoid need for clib;
  39. int
  40. strlen( char* a );
  41. int
  42. strlen( char* a )
  43. {
  44.     int i=0;
  45.     for( ; *a; a++ ) i++;
  46.     return i;
  47. }
  48.  
  49. void
  50. strcpy( char* a, char* b );
  51. void
  52. strcpy( char* a, char* b )
  53. {
  54.     for( ; *b; b++,a++ ) *a = *b;
  55.     *a = *b;
  56. }
  57.  
  58. void
  59. strncpy( char* a, char* b, int i );
  60. void
  61. strncpy( char* a, char* b, int i )
  62. {
  63.     for( ; i; b++,a++,i-- ) *a = *b;
  64.     //*a = '\0';
  65. }
  66.  
  67. char*
  68. strcat( char* a, char* b );
  69. char*
  70. strcat( char* a, char* b )
  71. {
  72.     char*    c = a;
  73.     while( *a++ ) {}
  74.     --a;    // we've overstepped, backup one.
  75.     for( ; *b; b++,a++ ) *a = *b;
  76.     *a = *b;
  77.     return c;
  78. }
  79. #else
  80. #include    <string.h>
  81. #endif
  82.  
  83. // allocated when xcmdBase object is instantiated
  84. XCmdPtr    
  85. xcmdString::paramPtr    = nil;
  86.  
  87. // I could calculate this once for each instantiation but
  88. //    I don't often need it.  Calculate when needed.
  89. int
  90. xcmdString::length( void ) const
  91. {
  92.     return len;        // The string length.
  93. }
  94.  
  95. //    Wipe pointer, return storage.
  96. xcmdString::~xcmdString()
  97. {
  98.     if ( str != nil )    delete [] str;
  99. }
  100.  
  101. xcmdString::xcmdString() : len(0)
  102. {
  103.     str = nil;
  104. }
  105.  
  106. #pragma    mark -
  107. #pragma mark • Creation Operators…
  108. // from null length handle.
  109. xcmdString::xcmdString( Handle s, Boolean useHandLen )
  110. {
  111.     if ( useHandLen ) 
  112.         len = ::GetHandleSize( s );
  113.     else
  114.         len = strlen(*s);
  115.     
  116.     str = new char[len+2];
  117.         ThrowIfNil_( str );
  118. //    HLock( s );
  119. //    strcpy( cStr(), *s );
  120.     strncpy( cStr(), *s, len+1 );
  121. //    HUnlock( s );
  122.     str[0] = len>MAX_PSIZE ? MAX_PSIZE : len;
  123. }
  124.  
  125. // copy operator
  126. xcmdString::xcmdString( xcmdString& s )
  127.     len = s.length();
  128.     str = new char[len+2];
  129.         ThrowIfNil_( str );
  130.     // copy strlen pointer and all.
  131.     strncpy( str, (char*)s.pStr(), len+2 );
  132. }
  133.  
  134. // from c string
  135. xcmdString::xcmdString( char* s )
  136.     len = strlen(s);
  137.     str = new char[len+2];
  138.         ThrowIfNil_( str );
  139.     strcpy( cStr(), s );
  140.     str[0] = len>MAX_PSIZE ? MAX_PSIZE : len;
  141.     str[len+1]    = '\0';    // null terminate
  142. }
  143.  
  144. // from pointer
  145. xcmdString::xcmdString( char* s, long n )
  146.     len = n;
  147.     str = new char[len+2];
  148.         ThrowIfNil_( str );
  149.     strncpy( cStr(), s, n );
  150.     str[0] = len>MAX_PSIZE ? MAX_PSIZE : len;
  151.     str[len+1]    = '\0';    // null terminate
  152. }
  153.  
  154. // from pascal string
  155. xcmdString::xcmdString( StringPtr s )
  156.     len = s[0];
  157.     str = new char[len+2];
  158.         ThrowIfNil_( str );
  159.     strncpy( str, (char*)s, len+1 );
  160.     str[len+1]    = '\0';    // null terminate
  161. }
  162.  
  163. /****  String Conversions  ****/
  164. xcmdString::xcmdString( Boolean bool )
  165. {
  166.     str = new char[8];
  167.         ThrowIfNil_( str );
  168.     
  169.     BoolToStr( paramPtr, bool, StringPtr(str) );
  170.     len = str[0];
  171.     str[len+1]    = '\0';    // null terminate
  172. }
  173.  
  174. xcmdString::xcmdString( double_t num )
  175. {
  176.     str = new char[20];
  177.         ThrowIfNil_( str );
  178.  
  179.     Double_tToStr( paramPtr, num, StringPtr(str) ); 
  180.     len = str[0];
  181.     str[len+1]    = '\0';    // null terminate
  182. }
  183.  
  184. xcmdString::xcmdString( unsigned long posNum )
  185. {
  186.     str = new char[20];
  187.         ThrowIfNil_( str );
  188.  
  189.     LongToStr( paramPtr, long(posNum), StringPtr(str) ); 
  190.     len = str[0];
  191.     str[len+1]    = '\0';    // null terminate
  192. }
  193.  
  194. xcmdString::xcmdString( long num, short nd )
  195. {
  196.     str = new char[nd+4];
  197.         ThrowIfNil_( str );
  198.  
  199.     NumToHex( paramPtr, num, nd, StringPtr(str) );
  200.     len = str[0];
  201.     str[len+1]    = '\0';    // null terminate
  202. }
  203.  
  204. xcmdString::xcmdString( long num )
  205. {
  206.     str = new char[20];
  207.         ThrowIfNil_( str );
  208.  
  209.     NumToStr( paramPtr, num, StringPtr(str) ); 
  210.     len = str[0];
  211.     str[len+1]    = '\0';    // null terminate
  212. }
  213.  
  214. xcmdString::xcmdString( Point pt )
  215. {
  216.     str = new char[15];
  217.         ThrowIfNil_( str );
  218.  
  219.     PointToStr( paramPtr, pt, StringPtr(str) );
  220.     len = str[0];
  221.     str[len+1]    = '\0';    // null terminate
  222. }
  223.  
  224. xcmdString::xcmdString( Rect& rct )
  225. {
  226.     str = new char[30];
  227.         ThrowIfNil_( str );
  228.  
  229.     RectToStr( paramPtr, &rct, StringPtr(str) ); 
  230.     len = str[0];
  231.     str[len+1]    = '\0';    // null terminate
  232. }
  233.  
  234. #pragma    mark -
  235. #pragma    mark • Operators…
  236. // conversion operators for useful types:
  237. xcmdString::operator Boolean() const
  238. {
  239.     Boolean rc = StrToBool( paramPtr, StringPtr(str) );
  240.     return rc;
  241. }
  242.  
  243. xcmdString::operator Rect() const
  244. {
  245.         Rect    rct;
  246.     StrToRect( paramPtr, StringPtr(str), &rct );
  247.     return rct;
  248. }
  249.  
  250. xcmdString::operator Point() const
  251. {
  252.         Point    pt;
  253.     StrToPoint( paramPtr, pStr(), &pt );
  254.     return pt;
  255. }
  256.  
  257. xcmdString::operator double_t() const
  258. {
  259.     double_t e = StrToDouble_t( paramPtr, pStr() ); 
  260.     return e;
  261. }
  262.  
  263. xcmdString::operator unsigned long() const
  264. {
  265.     unsigned long d = StrToLong( paramPtr, pStr() ); 
  266.     return d;
  267. }
  268.  
  269. xcmdString::operator long() const
  270. {
  271.     unsigned long d = StrToNum( paramPtr, pStr() ); 
  272.     return d;
  273. }
  274.  
  275. xcmdString::operator StringPtr() const
  276. {
  277.     return pStr();
  278. }
  279.  
  280. xcmdString::operator char*() const
  281. {
  282.     return cStr();
  283. }
  284.  
  285. // I create a handle, copy data, hand it off. You must manage it!
  286. xcmdString::operator Handle() const
  287. {
  288.     Handle h;
  289.     
  290.     h = NewHandleClear (length() + 1);
  291.     if ( h )
  292.         strcpy( (char *) *h, cStr() );
  293.     
  294.     return h;
  295. }
  296.  
  297. #pragma    mark -
  298. #pragma mark • Testing operations…
  299. // Some key testing operators. == != contains
  300. //    ____________________________________
  301. long            
  302. xcmdString::contains( const xcmdString& s2 ) const
  303. {
  304.     char*    op    =    (char*)StringMatch( paramPtr, s2, cStr() );
  305.     if ( op == nil ) return 0;
  306.     return op-str;
  307. }
  308.  
  309. Boolean
  310. operator!=( const xcmdString& s1, const xcmdString& s2 )
  311. {
  312.     Boolean    rc    =    StringEqual( xcmdString::paramPtr, s1.pStr(), s2.pStr() );
  313.     return !rc;
  314. }
  315.  
  316. // Equate.  Is a friend so that "" clauses are handled automaticlly
  317. //    ____________________________________
  318. Boolean
  319. operator==( const xcmdString& s1, const xcmdString& s2 )
  320. {
  321.     Boolean    rc    =    StringEqual( xcmdString::paramPtr, s1.pStr(), s2.pStr() );
  322.     return rc;
  323. }
  324.  
  325. // overloading of assignment.
  326. //    ____________________________________
  327. xcmdString&
  328. xcmdString::operator=( const xcmdString& s2 )
  329. {
  330.     if ( this != &s2 ) {
  331.         if ( str != nil )    delete [] str;
  332.         len =  s2.length();
  333.         str = new char[len+2];
  334.             ThrowIfNil_( str );
  335.         // copy strlen pointer and all.
  336.         strncpy( str, (char*)s2.pStr(), len+2 );
  337.         }
  338.     return *this;
  339. }
  340.  
  341. xcmdString&
  342. xcmdString::operator&=( const xcmdString& s2 )
  343. {
  344.     char*    temp    =    str;
  345.  
  346.     len +=  s2.length();
  347.     str = new char[len+2];
  348.         ThrowIfNil_( str );
  349.  
  350.     if ( temp != nil ) {
  351.         strcpy( cStr(), &temp[1] );
  352.         delete [] temp;
  353.         }
  354.     
  355.     strcat( cStr(), s2.cStr() );
  356.     
  357.     str[0] = len>MAX_PSIZE ? MAX_PSIZE : len;
  358.  
  359.     return *this;
  360. }
  361.  
  362. // overloading of index to return specific element.
  363. //    ____________________________________
  364. char
  365. xcmdString::operator[]( const int i )
  366. {
  367.     if ( i>length() ) return '\0';
  368.     return cStr()[i];
  369. }
  370.  
  371. // Catenation.  Is a friend so that "" are handled automaticlly
  372. //    ____________________________________
  373. xcmdString
  374. operator&( const xcmdString& s1, const xcmdString& s2 )
  375. {
  376.     char*    s    =    new    char[ s1.length() + s2.length() + 2 ];
  377.         ThrowIfNil_( s );
  378.     strcpy( s, s1.cStr() );
  379.     xcmdString    rs( strcat( s, s2.cStr() ) );
  380.     delete [] s;
  381.     return rs;
  382. }
  383.  
  384. #pragma    mark -
  385. #pragma mark • Conditioning operations…
  386. void
  387. xcmdString::trimWhiteSpace( void )
  388. {
  389.     char*    sp    =    cStr();
  390.     
  391.     while( *sp == ' ' || *sp == '\t' || *sp == '\r' ) sp++;
  392.  
  393.     ::BlockMove( sp, cStr(), length() );
  394.     
  395.     len = strlen(cStr());
  396.     while( str[len] == ' ' || str[len] == '\t' || str[len] == '\r' ) len--;
  397.  
  398.     str[0] = len>MAX_PSIZE ? MAX_PSIZE : len;
  399.     str[len+1]    = '\0';    // null terminate
  400.  
  401. }
  402.  
  403.